#jinja2: lstrip_blocks: True
{%- set external_tls_bind_info = 'ssl crt /etc/haproxy/haproxy.pem' if kolla_enable_tls_external|bool else '' %}
{%- set internal_tls_bind_info = 'ssl crt /etc/haproxy/haproxy-internal.pem' if kolla_enable_tls_internal|bool else '' %}

{%- macro userlist_macro(service_name, auth_user, auth_pass) %}
userlist {{ service_name }}-user
  user {{ auth_user }} insecure-password {{ auth_pass }}
{% endmacro %}

{%- macro listen_macro(service_name, service_port, listen_port,
                       service_mode, external,
                       haproxy_http_extra, haproxy_tcp_extra, host_group,
                       custom_member_list, auth_user, auth_pass, tls_backend) %}
listen {{ service_name }}
    {% if service_mode == 'redirect' %}
    mode http
    {% else %}
    mode {{ service_mode }}
    {% endif %}
    {% if service_mode == 'http' %}
        {# Set up auth if required #}
        {% if auth_user and auth_pass %}
    acl auth_acl http_auth({{ service_name }}-user)
    http-request auth realm basicauth unless auth_acl
        {% endif %}
    {# Delete any pre-populated XFP header #}
    http-request del-header X-Forwarded-Proto
        {% for http_option in haproxy_http_extra %}
    {{ http_option }}
        {% endfor %}
    {% elif service_mode == 'tcp' %}
        {% for tcp_option in haproxy_tcp_extra %}
    {{ tcp_option }}
        {% endfor %}
    {% endif %}
    {% set tls_option = '' %}
    {% if external|bool %}
        {% set vip_address = kolla_external_vip_address %}
        {% if service_mode == 'http' %}
            {% set tls_option = external_tls_bind_info %}
    {# Replace the XFP header for external https requests #}
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
        {% endif %}
    {% else %}
        {% set vip_address = kolla_internal_vip_address %}
        {% if service_mode == 'http' %}
            {% set tls_option = internal_tls_bind_info %}
    {# Replace the XFP header for internal https requests #}
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
        {% endif %}
    {% endif %}
    {{ "bind %s:%s %s"|e|format(vip_address, service_port, tls_option)|trim() }}
    {# Redirect mode sets a redirect scheme instead of members #}
    {% if service_mode == 'redirect' %}
    redirect scheme https code 301 if !{ ssl_fc }
    {% else %}
        {% if custom_member_list is not none %}
            {% for custom_member in custom_member_list %}
    {{ custom_member }}
            {% endfor %}
        {% else %}
            {% set backend_tls_info = '' %}
            {% if tls_backend|bool %}
                {% set haproxy_health_check_final = haproxy_health_check_ssl %}
                {% if kolla_verify_tls_backend|bool %}
                    {% set backend_tls_info = 'ssl verify required ca-file %s'|format(haproxy_backend_cacert) %}
                {% else %}
                    {% set backend_tls_info = 'ssl verify none' %}
                {% endif %}
            {% else %}
                {% set haproxy_health_check_final = haproxy_health_check %}
            {% endif %}
            {% for host in groups[host_group] %}
                {% set host_name = hostvars[host]['ansible_hostname'] %}
                {% set host_ip = 'api' | kolla_address(host) %}
    server {{ host_name }} {{ host_ip }}:{{ listen_port }} {{ haproxy_health_check_final }} {{ backend_tls_info }}
            {% endfor %}
        {% endif %}
    {% endif %}
{% endmacro %}

{%- set haproxy = service.haproxy|default({}) %}
{%- for haproxy_name, haproxy_service in haproxy.items() %}
    {# External defaults to false #}
    {% set external = haproxy_service.external|default(false)|bool %}
    {# Skip anything that is external when the external vip is not enabled #}
    {% if haproxy_service.enabled|bool and (not external or haproxy_enable_external_vip|bool)%}
        {# Here we define variables and their defaults #}
        {# services can be listening on a different port than haproxy #}
        {% set listen_port = haproxy_service.listen_port|default(haproxy_service.port) %}
        {# Custom member list can use jinja to generate a semicolon separated list #}
        {% set custom_member_list = haproxy_service.custom_member_list|default(none) %}
        {# Mode defaults to http #}
        {% set mode = haproxy_service.mode|default('http') %}
        {# Use the parent host group but allow it to be overridden #}
        {% set host_group = haproxy_service.host_group|default(service.group) %}
        {# Additional options can be defined in config, and are additive to the global extras #}
        {% set haproxy_tcp_extra = haproxy_service.frontend_tcp_extra|default([]) + haproxy_service.backend_tcp_extra|default([]) + haproxy_frontend_tcp_extra + haproxy_backend_tcp_extra %}
        {% set haproxy_http_extra = haproxy_service.frontend_http_extra|default([]) + haproxy_service.backend_http_extra|default([]) + haproxy_frontend_http_extra + haproxy_backend_http_extra %}
        {% set tls_backend = haproxy_service.tls_backend|default(false) %}
        {# Allow for basic auth #}
        {% set auth_user = haproxy_service.auth_user|default() %}
        {% set auth_pass = haproxy_service.auth_pass|default() %}
        {% if auth_user and auth_pass %}
{{ userlist_macro(haproxy_name, auth_user, auth_pass) }}
        {% endif %}
{{ listen_macro(haproxy_name, haproxy_service.port, listen_port,
                mode, external, haproxy_http_extra, haproxy_tcp_extra,
                host_group, custom_member_list, auth_user, auth_pass, tls_backend) }}
    {% endif %}
{%- endfor -%}
